package com.qipay.cpaccount.impl;

import com.qipay.baas.model.CpAccount;
import com.qipay.baas.model.CpWithdrawTradlog;
import com.qipay.baas.model.Order;
import com.qipay.cpaccount.CpAccountService;
import com.qipay.cpaccount.CpAccountTradLogService;
import com.qipay.mapper.CpAccountMapper;
import com.qipay.withdraw.config.WithdrawTypeEnum;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

@Service
public class CpAccountServiceImpl implements CpAccountService {


    Logger logger = LogManager.getLogger(CpAccountServiceImpl.class);


    @Autowired
    CpAccountMapper cpAccountMapper;
    @Autowired
    CpAccountTradLogService cpAccountTradLogService;


    @Override
    public CpAccount get(long id) {
        return cpAccountMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional
    public int update(CpAccount cpAccount) {
        return cpAccountMapper.updateByPrimaryKey(cpAccount);
    }

    @Override
    @Transactional
    public void create(CpAccount cpAccount) {
        cpAccountMapper.insert(cpAccount);
    }


    @Override
    @Transactional
    public void setOrderSuccess(Order order) {
        CpAccount cpAccount = get(order.getCpId());
        if (cpAccount == null) {
            cpAccount.setCpId(order.getCpId());
            cpAccount.setBalanceAdvance((long) order.getAdvanceAmount());
            cpAccount.setBalanceDisabled((long) order.getDisableAmount());
            cpAccount.setBalance((long) order.getActualAmount());
            create(cpAccount);
        } else {
            Long amountChange = Long.valueOf(order.getAmount());
            Byte type = order.getSettleStatus();

            int base = order.getState()==99 ? -1 : 1;

            Long BalanceChange = base==1?order.getActualAmount():amountChange;
            cpAccount.setBalance(cpAccount.getBalance()+base*BalanceChange);
            cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable()+base*BalanceChange);
            update(cpAccount);
            if(base==-1)return;
        }
        if(order.getAgentId() != null){
            CpAccount agent = get(order.getAgentId());
            Long agentBalance = (long) (order.getFee() - order.getAgentFee());
            if (agentBalance > 0) {
                if (agent == null) {
                    agent.setCpId(order.getAgentId());
                    agent.setBalanceAvailable(agentBalance);
                    agent.setBalance(agentBalance);
                    create(cpAccount);
                } else {
                    agent.setBalanceAvailable(agent.getBalanceAvailable() + agentBalance);
                    agent.setBalance(agent.getBalance() + agentBalance);
                    update(agent);
                }
            }
        }

    }

    //*************此方法，原来是模拟t1，是计算总余额，垫资余额，可用余额，不可用余额的，已提金额的
//    @Override
//    @Transactional
//    public void setOrderSuccess(Order order) {
//        CpAccount cpAccount = get(order.getCpId());
//        if (cpAccount == null) {
//            cpAccount.setCpId(order.getCpId());
//            cpAccount.setBalanceAdvance((long) order.getAdvanceAmount());
//            cpAccount.setBalanceDisabled((long) order.getDisableAmount());
//            cpAccount.setBalance((long) order.getActualAmount());
//            create(cpAccount);
//        } else {
//            Long amountChange = Long.valueOf(order.getAmount());
//            Byte type = order.getSettleStatus();
//
//            int base = order.getState()==99 ? -1 : 1;
//
//            Long BalanceChange = base==1?order.getActualAmount():amountChange;
//            cpAccount.setBalance(cpAccount.getBalance()+base*BalanceChange);
//
//            Long BalanceAdvanceChange = base==1?order.getAdvanceAmount():(type.equals(WithdrawTypeEnum.ADVANCE.getType()) ? amountChange : 0l);
//            cpAccount.setBalanceAdvance(cpAccount.getBalanceAdvance()+base*BalanceAdvanceChange);
//
//            Long BalanceDisabledChange = base==1?order.getDisableAmount():0l;
//            cpAccount.setBalanceDisabled(cpAccount.getBalanceDisabled()+BalanceDisabledChange);
//
//            Long BalanceAvailableChange = base==1?0l:(type.equals(WithdrawTypeEnum.AVAILABLE.getType()) ? amountChange : 0l);
//            cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable()+base*BalanceAvailableChange);
//
//            Long BalanceAdvanceWidthdrawChange = base==1?0l:(type.equals(WithdrawTypeEnum.ADVANCE.getType()) ? amountChange : 0l);
//            cpAccount.setBalanceAdvanceWidthdraw(cpAccount.getBalanceAdvanceWidthdraw()+BalanceAdvanceWidthdrawChange);
//
//            update(cpAccount);
//            if(base==-1)return;
//        }
//        if(order.getAgentId() != null){
//            CpAccount agent = get(order.getAgentId());
//            Long agentBalance = (long) (order.getFee() - order.getAgentFee());
//            if (agentBalance > 0) {
//                if (agent == null) {
//                    agent.setCpId(order.getAgentId());
//                    agent.setBalanceDisabled(agentBalance);
//                    agent.setBalance(agentBalance);
//                    create(cpAccount);
//                } else {
//                    agent.setBalanceDisabled(agent.getBalanceDisabled() + agentBalance);
//                    agent.setBalance(agent.getBalance() + agentBalance);
//                    update(agent);
//                }
//            }
//        }
//
//    }

    @Override
    @Transactional
    public void setWithdrawApply(CpWithdrawTradlog cpWithdrawTradlog) {
        CpAccount cpAccount = get(cpWithdrawTradlog.getCpId());
        if (cpWithdrawTradlog.getType() == WithdrawTypeEnum.AVAILABLE.getType()) {
            Assert.isTrue(cpAccount.getBalanceAvailable() >= cpWithdrawTradlog.getAmount(), "帐户余额不足");
            cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() - cpWithdrawTradlog.getAmount());
        } else {
            Assert.isTrue(cpAccount.getBalanceAdvance() >= cpWithdrawTradlog.getAmount(), "帐户余额不足");
            cpAccount.setBalanceAdvance(cpAccount.getBalanceAdvance() - cpWithdrawTradlog.getAmount());
            cpAccount.setBalanceAdvanceWidthdraw(cpAccount.getBalanceAdvanceWidthdraw() + cpWithdrawTradlog.getAmount());
        }
        cpAccount.setBalance(cpAccount.getBalance() - cpWithdrawTradlog.getAmount());
        update(cpAccount);
    }

    @Override
    @Transactional
    public void setWithdrawFail(CpWithdrawTradlog cpWithdrawTradlog) {
        CpAccount cpAccount = get(cpWithdrawTradlog.getCpId());
        if (cpWithdrawTradlog.getType() == WithdrawTypeEnum.AVAILABLE.getType()) {
            cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + cpWithdrawTradlog.getAmount());
        } else {
            cpAccount.setBalanceAdvance(cpAccount.getBalanceAdvance() + cpWithdrawTradlog.getAmount());
            cpAccount.setBalanceAdvanceWidthdraw(cpAccount.getBalanceAdvanceWidthdraw() - cpWithdrawTradlog.getAmount());
        }
        cpAccount.setBalance(cpAccount.getBalance() + cpWithdrawTradlog.getAmount());
        update(cpAccount);
    }

    @Transactional
    @Override
    public void setOrderDone(Order order) {
        CpAccount cpAccount = get(order.getCpId());
        Assert.notNull(cpAccount, "无法找到CP信息");

        if (cpAccount.getBalanceAdvanceWidthdraw() > 0) {
            if (cpAccount.getBalanceAdvanceWidthdraw() >= order.getAdvanceAmount()) {
                cpAccount.setBalanceAdvanceWidthdraw(cpAccount.getBalanceAdvanceWidthdraw() - order.getAdvanceAmount());
            } else {
                long balance = order.getAdvanceAmount() - cpAccount.getBalanceAdvanceWidthdraw();
                cpAccount.setBalanceAdvanceWidthdraw((long) 0);
                if (cpAccount.getBalanceAdvance() >= balance) {
                    cpAccount.setBalanceAdvance(cpAccount.getBalanceAdvance() - balance);
                    cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + balance);
                } else {
                    cpAccount.setBalanceAdvance((long) 0);
                    cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + balance);
                }
            }
        } else {
            if (cpAccount.getBalanceAdvance() >= order.getAdvanceAmount()) {
                cpAccount.setBalanceAdvance(cpAccount.getBalanceAdvance() - order.getAdvanceAmount());
                cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + order.getAdvanceAmount());
            } else {
                cpAccount.setBalanceAdvance((long) 0);
                cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + cpAccount.getBalanceAdvance());
            }
        }

        if (cpAccount.getBalanceDisabled() >= order.getDisableAmount()) {
            cpAccount.setBalanceDisabled(cpAccount.getBalanceDisabled() - order.getDisableAmount());
            cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + order.getDisableAmount());
        } else {
            cpAccount.setBalanceDisabled((long) 0);
            cpAccount.setBalanceAvailable(cpAccount.getBalanceAvailable() + cpAccount.getBalanceDisabled());
        }
        cpAccountMapper.updateByPrimaryKey(cpAccount);

        if (order.getAgentId() != null) {
            CpAccount agent = get(order.getAgentId());
            if (agent != null) {
                Long agentBalance = (long) (order.getFee() - order.getAgentFee());
                if (agentBalance > 0) {
                    if (agent.getBalanceDisabled() >= agentBalance) {
                        agent.setBalanceDisabled(agent.getBalanceDisabled() - agentBalance);
                        agent.setBalanceAvailable(agent.getBalanceAvailable() + agentBalance);
                    } else {
                        agent.setBalanceDisabled((long) 0);
                        agent.setBalanceAvailable(agent.getBalanceAvailable() + agent.getBalanceDisabled());
                    }
                    cpAccountMapper.updateByPrimaryKey(agent);
                }
            }
        }
        cpAccountTradLogService.setOrderFinish(order);
    }

    @Override
    @Transactional
    public void adjust(Long cpId, Long balanceChange, Long balanceAvailableChange, Long balanceAdvanceChange, Long balanceDisabledChange, Long balanceAdvanceWidthdrawChange) {

        // log
        logger.info(String.format("adjust(%s, %s, %s, %s, %s, %s)", cpId, balanceChange, balanceAvailableChange, balanceAdvanceChange, balanceDisabledChange, balanceAdvanceWidthdrawChange));

        // adjust
        cpAccountMapper.adjust(cpId, balanceChange, balanceAvailableChange, balanceAdvanceChange, balanceDisabledChange, balanceAdvanceWidthdrawChange);
    }
}
